﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SMSClassLibrary;
using System.IO;
using System.Threading;

namespace WindowsFormsApplication1
{
    public partial class SendBulkSMS : Form
    {
        public SendBulkSMS()
        {
            InitializeComponent();
            CurrentAppContext = SynchronizationContext.Current;
            UserNumber = System.Configuration.ConfigurationManager.AppSettings["User"];
            UserPassword = Cry System.Configuration.ConfigurationManager.AppSettings["Password"];
            ServiceName = System.Configuration.ConfigurationManager.AppSettings["Service"];

        }
        SynchronizationContext CurrentAppContext;
        
        private void UpdateCurrentLabel(object oEntity)
        {
            UpdateEntity oCurrentEntity = (UpdateEntity)oEntity;
            oCurrentEntity.CurrentLabel.Text = oCurrentEntity.Status;
            Application.DoEvents();
        }
        int TRIAL_NO = 0;
        string sNumberFilePath = "";
        string UserNumber = null;
    string UserPassword = null;
    string ServiceName = null;

        private void btnSendSMS_Click(object sender, EventArgs e)
        {
            try
            {

                RestLabels();
                if (!ValidateInfo())
                {
                    MessageBox.Show("Any of required information MobileNo , Password , Service Provider is missing .");
                    return;
                }
                List<string> lstNoToSend = new List<string>();
                
                FileStream fs = null;
                
                if (chkConfirmGroup.Checked)
                {
                    if (String.IsNullOrEmpty(sNumberFilePath))
                    {
                        sNumberFilePath = @"Numbers.txt";
                    }
                }
                else
                {
                    sNumberFilePath = @"SafeCopyOfNos.txt";
                }
                if (File.Exists(sNumberFilePath))
                {
                    fs = new FileStream(sNumberFilePath, FileMode.Open);
                }
                else
                {
                    MessageBox.Show("File Not found.");
                    return;
                }

                StreamReader sr = new StreamReader(fs);
                string message = rtbMessage.Text;
                while (true)
                {
                    string sNo = sr.ReadLine();
                    if (String.IsNullOrEmpty(sNo))
                    {
                        break;
                    }
                    else
                    {
                        lstNoToSend.Add(sNo);
                    }
                }
                sr.Close();
                fs.Close();
                TRIAL_NO = 1;
                List<string> lstFailedNos1 = SendMessageToListNumbers(lstNoToSend, message);
                UpdateLabelsData(lblFirstCurrent, lstNoToSend.Count, lblFirstSuccess, lstNoToSend.Count - lstFailedNos1.Count, lblFirstFail, lstFailedNos1.Count);
                TRIAL_NO = 2;
                List<string> lstFailedNos2 = SendMessageToListNumbers(lstFailedNos1, message);
                UpdateLabelsData(lblSecondCurrent, lstFailedNos1.Count, lblSecondSuccess, lstFailedNos1.Count - lstFailedNos2.Count, lblSecondFail, lstFailedNos2.Count);
                TRIAL_NO = 3;
                List<string> lstFailedNos3 = SendMessageToListNumbers(lstFailedNos2, message);
                UpdateLabelsData(lblThirdCurrent, lstFailedNos2.Count, lblThirdSuccess, lstFailedNos2.Count - lstFailedNos3.Count, lblThirdFail, lstFailedNos3.Count);
                if (lstFailedNos3.Count > 0)
                {
                    WriteToErrorFile("****************  **********************");
                    WriteToErrorFile("****************  Message could not be sent to following nos :**********************");
                    foreach (string s in lstFailedNos3)
                    {
                        WriteToErrorFile("Error :" + ex.Message);
                    }
                    MessageBox.Show("Done. For failed mobile nos. please view log file.");
                }
                else
                {
                    MessageBox.Show("Done");
                }
            }
            catch (System.Exception ex)
            {
                WriteToErrorFile("Error :" + ex.Message);
            }

        }

        private bool ValidateInfo()
        {
            if (String.IsNullOrEmpty(UserNumber) || String.IsNullOrEmpty(UserPassword) || String.IsNullOrEmpty(ServiceName))
            {
                return false;
            }
            if (UserNumber.Length < 10)
            {
                return false;
            }
            return true;
        }

        private void RestLabels()
        {
            lblFirstCurrent.Text = lblFirstFail.Text = lblFirstSuccess.Text = lblFirstTotal.Text = "";
            lblSecondCurrent.Text = lblSecondFail.Text = lblSecondSuccess.Text = lblSecondTotal.Text = "";
            lblThirdCurrent.Text = lblThirdFail.Text = lblThirdSuccess.Text = lblThirdTotal.Text = "";
        }
        private void UpdateLabelsData(Label lblCurrent, int iCompleted, Label lblSuccess, int iSuccess, Label lblFail, int iFail)
        {
            lblCurrent.Text = iCompleted.ToString();
            lblSuccess.Text = iSuccess.ToString();
            lblFail.Text = iFail.ToString();
        }
        private List<string> SendMessageToListNumbers(List<string> lstNoToSend, string message)
        {
            int count = 0;
            UpdateTotal(lstNoToSend.Count);
            List<string> lstFailedNumbers = new List<string>();
            UpdateEntity oEntity = new UpdateEntity();
            switch (TRIAL_NO)
            {
                case 1:
                    oEntity.CurrentLabel = lblFirstCurrent;
                    break;
                case 2:
                    oEntity.CurrentLabel = lblSecondCurrent;
                    break;
                case 3:
                    oEntity.CurrentLabel = lblThirdCurrent;
                    break;
            }
            foreach (string sNo in lstNoToSend)
            {
                try
                {
                    count++;
                    string sRes = SendSMS(sNo, message);
                    if (sRes == "1")
                    {
                        // 1 means SMS sent,
                        //-1 means some server error, 
                        //-2 means invalid username, 
                        //-3 means invalid message text, 
                        //-4 means login failed.
                    }
                    else
                    {
                        lstFailedNumbers.Add(sNo);
                    }
                    oEntity.Status = count.ToString();
                    CurrentAppContext.Send(UpdateCurrentLabel, oEntity);
                }
                catch (System.Exception ex)
                {
                    WriteToErrorFile("Error with No " + sNo + " :" + ex.Message);
                }
            }
            return lstFailedNumbers;
        }

        private void UpdateTotal(int lstCount)
        {
            switch (TRIAL_NO)
            {
                case 1:
                    lblFirstTotal.Text = lstCount.ToString();
                    break;
                case 2:
                    lblSecondTotal.Text = lstCount.ToString();
                    break;
                case 3:
                    lblThirdTotal.Text = lstCount.ToString();
                    break;
            }
        }
        private void ShowResult(int iCount)
        {
            //lblResult.Text = "Done :"+iCount.ToString();
        }
        private string SendSMS(string number, string message)
        {
            ReddyInfoSoft ris = new ReddyInfoSoft();
            string res = ris.sendSMS(UserNumber,UserPassword, message, number, ServiceName);
            return res;
        }
        public static void WriteToErrorFile(string str)
        {
            FileStream fs = null;
            //string sFileName = GetFileName(sType);
            if (File.Exists("log.txt"))
            {
                fs = new FileStream("log.txt", FileMode.Append);
            }
            else
            {
                fs = new FileStream("log.txt", FileMode.Create);
            }
            StreamWriter sw = new StreamWriter(fs);
            sw.WriteLine(Environment.NewLine);
            sw.WriteLine(str);
            sw.Close();
            fs.Close();

        }
        
        private void rtbMessage_TextChanged(object sender, EventArgs e)
        {
            UpdateLeftCount();
        }
        private void UpdateLeftCount()
        {
            int leftCount = 140 - rtbMessage.TextLength;
            lblLeftChar.Text = "Left : " + leftCount;
        }

        private void btnSelectFile_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFile = new OpenFileDialog();
                openFile.Multiselect = false;
                openFile.InitialDirectory = "C:\\";
                openFile.Filter = "Test file (*.txt)|*.txt";
                DialogResult result = openFile.ShowDialog();
                if (result == System.Windows.Forms.DialogResult.OK)
                {

                    if (openFile.FileNames.Count() == 1)
                    {
                        tbFilePath.Text = openFile.FileName;
                        sNumberFilePath = openFile.FileName;
                    }
                    
                }
        }
    }
    public class UpdateEntity
    {
        public Label CurrentLabel { get; set; }
        public string Status { get; set; }
    }
}
